package com.huawei.windows;

import com.huawei.constants.CommonConstant;
import com.huawei.utils.HarmonyVersionUtil;
import com.huawei.utils.NotificationUtil;

import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.JBUI;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableCellEditor;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URI;
import java.util.Comparator;
import java.util.Objects;

public class ApiChangeAssistantToolWindow implements ToolWindowFactory, DumbAware {

    /**
     * to版本未晚于from版本，提示信息
     */
    private static final String VERSION_RULE_MESSAGE = "The start version must be earlier than target version.";

    @Override
    public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
        ApiChangeAssistantToolWindowContent toolWindowContent = new ApiChangeAssistantToolWindowContent(toolWindow,
            project);
        Content content = ContentFactory.getInstance().createContent(toolWindowContent.getContentPanel(), "", false);
        toolWindow.getContentManager().addContent(content);
    }

    private static class ApiChangeAssistantToolWindowContent {
        private final JPanel contentPanel;

        private JBTable table;

        private DefaultTableModel tableModel;

        private Project project;

        public ApiChangeAssistantToolWindowContent(ToolWindow toolWindow, Project project) {
            this.project = project;
            contentPanel = new JPanel(new BorderLayout());
            contentPanel.setBorder(JBUI.Borders.empty(10));

            // Add control panel at the top
            JPanel controlPanel = createControlPanel();

            // Create the table model with column names
            String[] columnNames = {
                "API Definition", "Language", "Changed in SDK", "Affected Versions", "Guidance link", "Code Location",
                "Operation"
            };
            tableModel = new DefaultTableModel(columnNames, 0) {
                @Override
                public boolean isCellEditable(int row, int column) {
                    // Make only the Operation column editable (for the button)
                    return column == 6;
                }

                @Override
                public Class<?> getColumnClass(int columnIndex) {
                    // Return JButton.class for the Operation column
                    return columnIndex == 6 ? JButton.class : String.class;
                }
            };

            // Create the table with the model
            table = new JBTable(tableModel) {
                @Override
                public TableCellRenderer getCellRenderer(int row, int column) {
                    if (column == 6) { // Operation column
                        return new ButtonRenderer();
                    } else if (column == 4) { // Guidance link column
                        return new LinkRenderer();
                    }
                    return super.getCellRenderer(row, column);
                }

                @Override
                public TableCellEditor getCellEditor(int row, int column) {
                    if (column == 6) { // Operation column
                        return new ButtonEditor(new JCheckBox(), this);
                    }
                    return super.getCellEditor(row, column);
                }
            };

            // Set up table properties
            table.setRowHeight(105); // Increase row height for better visibility
            table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
            table.getTableHeader().setReorderingAllowed(false);

            // Disable selection highlighting
            table.setSelectionBackground(table.getBackground());
            table.setSelectionForeground(table.getForeground());
            table.setFocusable(false);
            table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

            // Add table to a scroll pane
            JScrollPane scrollPane = new JScrollPane(table);
            contentPanel.add(controlPanel, BorderLayout.NORTH);
            contentPanel.add(scrollPane, BorderLayout.CENTER);

            // Add some sample data for demonstration
            addSampleData();

            // Add mouse listener for the link column
            table.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    int row = table.rowAtPoint(e.getPoint());
                    int col = table.columnAtPoint(e.getPoint());

                    if (col == 4 && row >= 0) { // Guidance link column
                        try {
                            Object value = table.getValueAt(row, col);
                            if (value != null) {
                                String url = value.toString();
                                Desktop.getDesktop().browse(new URI(url));
                            }
                        } catch (Exception ex) {
                            JOptionPane.showMessageDialog(contentPanel, "Could not open link: " + ex.getMessage(),
                                "Error", JOptionPane.ERROR_MESSAGE);
                        }
                    }
                }
            });
        }

        private void addSampleData() {
            // Add sample rows to demonstrate the table
            // In a real application, you would populate this with actual API data
            Object[] row1 = {
                "SampleAPI.method()", "Java", "SDK 2.0", "1.0 - 1.5", "https://example.com/guidance",
                "com.example.SampleClass:25", "Fix"
            };
            tableModel.addRow(row1);
        }

        // Renderer for the button in Operation column
        private static class ButtonRenderer implements TableCellRenderer {
            private final JButton button = new JButton("自动修复");

            private final JPanel panel = new JPanel(new GridBagLayout());

            public ButtonRenderer() {
                button.setOpaque(true);
                // Set fixed size for the button
                button.setPreferredSize(new Dimension(80, 35));
                panel.setOpaque(false);
                panel.add(button);
                // Ensure panel fills the entire cell
                panel.setBorder(BorderFactory.createEmptyBorder());
            }

            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                boolean hasFocus, int row, int column) {
                return panel;
            }
        }

        // Renderer for the link in Guidance link column
        private static class LinkRenderer implements TableCellRenderer {
            private final JLabel label = new JLabel();

            public LinkRenderer() {
                label.setOpaque(true);
                label.setForeground(Color.BLUE);
                // Add underline to look like a link
                label.setText("<html><u>Link</u></html>");
                label.setCursor(new Cursor(Cursor.HAND_CURSOR));
            }

            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                boolean hasFocus, int row, int column) {
                if (value != null) {
                    label.setText("<html><u>" + value.toString() + "</u></html>");
                }
                return label;
            }
        }

        // Editor for the button in the Operation column
        private static class ButtonEditor extends DefaultCellEditor {
            private JButton button;

            private String label;

            private boolean clicked;

            private final JTable table;

            public ButtonEditor(JCheckBox checkBox, JTable table) {
                super(checkBox);
                this.table = table;
                button = new JButton();
                button.setOpaque(true);
                // Set fixed size for the button
                button.setPreferredSize(new Dimension(80, 35));
                button.addActionListener(e -> fireEditingStopped());
            }

            @Override
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
                int column) {
                if (value instanceof String) {
                    label = (String) value;
                } else {
                    label = "Fix";
                }
                button.setText(label);
                clicked = true;

                // Create a panel to hold the button
                JPanel panel = new JPanel(new GridBagLayout());
                panel.setOpaque(false);
                panel.add(button);
                // Ensure panel fills the entire cell
                panel.setBorder(BorderFactory.createEmptyBorder());
                return panel;
            }

            @Override
            public Object getCellEditorValue() {
                if (clicked) {
                    // Handle the button click action here
                    JOptionPane.showMessageDialog(button,
                        "Fix action triggered for API at row: " + table.getSelectedRow());
                }
                clicked = false;
                return label;
            }

            @Override
            public boolean stopCellEditing() {
                clicked = false;
                return super.stopCellEditing();
            }
        }

        private JPanel createControlPanel() {
            // Main control panel with BorderLayout to have left and right components
            JPanel controlPanel = new JPanel(new BorderLayout());

            // Left-aligned components panel
            JPanel leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 2));

            // Version comparison text and dropdowns
            JLabel scanLabel = new JLabel("Scan the difference from");
            leftPanel.add(scanLabel);
            String[] versions = HarmonyVersionUtil.getVersions();
            JComboBox<String> fromVersionComboBox = new JComboBox<>(versions);
            // 默认选中
            String versionFromProfile = HarmonyVersionUtil.getSelectFromVersion(project.getBasePath());
            if (StringUtils.isNoneBlank(versionFromProfile)) {
                fromVersionComboBox.setSelectedItem(versionFromProfile);
            }
            leftPanel.add(fromVersionComboBox);

            JLabel toLabel = new JLabel("to");
            leftPanel.add(toLabel);
            JComboBox<String> toVersionComboBox = new JComboBox<>(versions);
            leftPanel.add(toVersionComboBox);

            // Add some spacing
            leftPanel.add(Box.createHorizontalStrut(6));

            // Add buttons
            JButton scanButton = new JButton("Start Scan");
            leftPanel.add(scanButton);

            // 创建规则提示标签
            JLabel ruleHintLabel = new JLabel("");
            ruleHintLabel.setForeground(Color.RED);
            leftPanel.add(ruleHintLabel);

            JButton exportButton = new JButton("Export");
            leftPanel.add(exportButton);

            // 初始化：检查form和to的版本关系
            checkVersionRule(fromVersionComboBox, toVersionComboBox, scanButton, ruleHintLabel);
            // 添加监听器：form下拉框
            fromVersionComboBox.addActionListener(
                e -> checkVersionRule(fromVersionComboBox, toVersionComboBox, scanButton, ruleHintLabel));
            // 添加监听器：to下拉框
            toVersionComboBox.addActionListener(
                e -> checkVersionRule(fromVersionComboBox, toVersionComboBox, scanButton, ruleHintLabel));

            // Add action listeners (empty for now)
            scanButton.addActionListener(e -> {
                // Add scan functionality here
                NotificationUtil.info(project, "start scan, please waiting...");
                startBackgroundTask(scanButton);
            });

            exportButton.addActionListener(e -> {
                // Add export functionality here
            });

            // Right-aligned components panel
            JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 2));

            // Add settings button
            JButton settingsButton = new JButton("Settings");
            rightPanel.add(settingsButton);

            // Add search field
            JTextField searchField = new JTextField(15);
            rightPanel.add(searchField);

            // Add action listener for settings button
            settingsButton.addActionListener(e -> {
                // Add settings functionality here
            });

            // Add panels to the main control panel
            controlPanel.add(leftPanel, BorderLayout.WEST);
            controlPanel.add(rightPanel, BorderLayout.EAST);

            return controlPanel;
        }

        public JPanel getContentPanel() {
            return contentPanel;
        }

        // 检查版本规则
        private void checkVersionRule(JComboBox<String> fromVersions, JComboBox<String> toVersions, JButton scanButton,
            JLabel ruleHintLabel) {
            Object selectedFormItem = fromVersions.getSelectedItem();
            Object selectedToItem = toVersions.getSelectedItem();
            if (selectedFormItem == null || selectedToItem == null) {
                scanButton.setEnabled(false);
                ruleHintLabel.setText(VERSION_RULE_MESSAGE);
                return;
            }
            // to版本必须大于from版本
            int compare = Objects.compare(selectedFormItem.toString(), selectedToItem.toString(),
                Comparator.naturalOrder());
            scanButton.setEnabled(compare < 0);
            ruleHintLabel.setText(compare < 0 ? "" : VERSION_RULE_MESSAGE);
        }

        private void startBackgroundTask(JButton scanButton) {
            // 创建一个后台任务
            Task.Backgroundable task = new Task.Backgroundable(project, CommonConstant.PLUGIN_NAME, true) {
                @Override
                public void run(@NotNull ProgressIndicator indicator) {
                    // indicator.setIndeterminate(true);
                    // 这是在后台线程中执行的代码
                    indicator.setText("processing...");
                    int total = 10;
                    for (int i = 1; i <= total; i++) {
                        // 检查任务是否被取消
                        if (indicator.isCanceled()) {
                            break;
                        }
                        // 模拟工作
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException ex) {
                            // 处理中断异常，通常任务取消时会中断线程
                            break;
                        }
                        // 更新进度
                        indicator.setFraction((double) i / total);
                        indicator.setText("process " + i * 10 + "%");
                    }
                }

                @Override
                public void onFinished() {
                    if (scanButton != null) {
                        scanButton.setEnabled(true); // 重新启用触发按钮
                    }
                }

                @Override
                public void onSuccess() {
                    NotificationUtil.info(project, "scan success!");
                }

                @Override
                public void onCancel() {
                    NotificationUtil.warn(project, "scan cancel!");
                }

                @Override
                public void onThrowable(@NotNull Throwable error) {
                    NotificationUtil.error(project, "scan error!");
                }
            };

            // 禁用按钮，防止重复点击
            scanButton.setEnabled(false);
            // 启动任务
            ProgressManager.getInstance().run(task);
        }
    }
}
